package cn.pugle.oj.leetcode;

import cn.pugle.oj.catalog.DesignProblem;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

/**
 * 错误写法, 有很多问题
 *
 * @author tzp
 * @since 2020/11/13
 */
public class LC355 implements DesignProblem {
    static class Twitter {
        public static final int SUPER_STAR = 1000;//关注超过1000就是super star

        HashMap<Integer, HashSet<Integer>> starToFans = new HashMap<>();
        HashMap<Integer, HashSet<Integer>> fansToSuperStar = new HashMap<>();
        HashMap<Integer, LinkedList<Integer>> superStarTweetBox = new HashMap<>();//superStar的话保留在自己的box
        HashMap<Integer, LinkedList<Integer>> receiveBox = new HashMap<>();//收件箱

        /**
         * Initialize your data structure here.
         */
        public Twitter() {
        }

        /**
         * Compose a new tweet.
         */
        public void postTweet(int userId, int tweetId) {
            if (superStarTweetBox.containsKey(userId)) {//is super start
                superStarTweetBox.get(userId).offerLast(tweetId);
            } else {
                for (Integer myFans : starToFans.get(userId)) {
                    receiveBox.compute(myFans, (key, oldValue) -> {
                        if (oldValue == null) oldValue = new LinkedList<>();
                        oldValue.offerLast(tweetId);
                        return oldValue;
                    });
                }
            }
        }

        public static List<Integer> last10(List<Integer> list) {
            if (list.size() >= 10) {
                return list.subList(list.size() - 10, list.size());
            } else {
                return list;
            }
        }

        /**
         * Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent.
         */
        public List<Integer> getNewsFeed(int userId) {
            LinkedList<Integer> all = new LinkedList<>(last10(receiveBox.get(userId)));
            for (Integer superStar : fansToSuperStar.get(userId)) {
                all.addAll(last10(superStarTweetBox.get(superStar)));
            }
            all.sort(Integer::compareTo);
            return last10(all);
        }

        /**
         * Follower follows a followee. If the operation is invalid, it should be a no-op.
         */
        public void follow(int fans, int star) {
            starToFans.compute(star, (key, oldValue) -> {
                if (oldValue == null) oldValue = new HashSet<>();
                oldValue.add(fans);
                return oldValue;
            });

            if (starToFans.get(star).size() >= SUPER_STAR) {//become super star
                superStarTweetBox.put(star, new LinkedList<>());
                for (Integer follower : starToFans.get(star)) {
                    fansToSuperStar.compute(follower, (key, oldValue) -> {
                        if (oldValue == null) oldValue = new HashSet<>();
                        oldValue.add(star);
                        return oldValue;
                    });
                }
            }
        }

        /**
         * Follower unfollows a followee. If the operation is invalid, it should be a no-op.
         */
        public void unfollow(int fans, int star) {//并没有写unfollow之后从super start降级
            starToFans.get(star).remove(fans);
            fansToSuperStar.get(fans).remove(star);
        }
    }

    public static void main(String[] args) {
        System.out.println(new LC355());
    }
}
